package com.eshin.connectionfactory;
import java.util.ArrayList;
import java.util.List;

import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.connection.RabbitConnectionFactoryBean;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.amqp.rabbit.core.RabbitMessagingTemplate;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.eshin.amqpconfig.ConnetctionConfig;
import com.eshin.amqpconfig.RabbitmqProperties;

public class RabbitMqConnectionFactory {
	@Configuration
	@ConditionalOnMissingBean(ConnectionFactory.class)
	@AutoConfigureBefore({SimpleRabbitListenerContainerFactory.class,RabbitMessagingTemplate.class})
	protected static class RabbitConnectionFactoryCreator {

		/**
		 * SimpleMessageListenerContainer直接使用该connectionFactory在自动回复后，无法监听
		 * 刚恢复的broker，因此该connectionFactory只对producer有效，comsumer需要使用该connectionFactory
		 * 中的connectionFactoryList逐个起监听
		 * @param config
		 * @return  
		 * @throws Exception
		 */
		@Bean("connectionFactory")
		public ConnectionFactory rabbitConnectionFactory(RabbitmqProperties config)
				throws Exception {
			
			List<CachingConnectionFactory>connectionFactoryList = new ArrayList<>();
			List<ConnetctionConfig>connects = config.getConnect();
			String username = config.getUsername();
			String password = config.getPassword();
			for(ConnetctionConfig connect : connects){
				RabbitConnectionFactoryBean factory = new RabbitConnectionFactoryBean();
				factory.setHost(connect.getHost());
				factory.setPort(connect.getPort());
				factory.setUsername(username);
				factory.setPassword(password);
				factory.afterPropertiesSet();
				CachingConnectionFactory connectionFactory = new CachingConnectionFactory(
						factory.getObject());
//     			connectionFactory.setAddresses(addressesStr);
				connectionFactoryList.add(connectionFactory);
			}
			MyConnectionFactory connectionFactory = new MyConnectionFactory(connectionFactoryList,config.getRecovery());
			connectionFactory.initExecutorService();
			return connectionFactory;
		}
		
		@Bean
		@ConditionalOnSingleCandidate(ConnectionFactory.class)
		public RabbitAdmin rabbitAdmin(@Qualifier("connectionFactory")ConnectionFactory connectionFactory){
			System.out.println("self rabbitAdmin");
			return new RabbitAdmin(connectionFactory);
		}
		
	    @Bean  
	    public RabbitTemplate rabbitTemplate(@Qualifier("connectionFactory")ConnectionFactory connectionFactory) {  
	        RabbitTemplate template = new RabbitTemplate(connectionFactory);  
	        return template;  
	    }  

	}
	
}
